<?php
/**
 * @describe 通用工具类
 *
 * @author wlx
 * @since 2018/11/2
 */

namespace App\Services;


use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Facades\Excel;

class GeneralTool
{
    /**
     * 文件上传到Oss
     *
     * @param string $filePath
     * @param string $ossKey
     * @param bool $needOptions
     *
     * @return string
     */
    public static function uploadFileToOssByFilePath($filePath, $ossKey, $needOptions = false)
    {
        try {
            if (!file_exists($filePath) || empty($ossKey)) {
                return '';
            }
            $options = [];
            if (!$needOptions) {
                $options = OssTool::getContentTypeOptionsByFilePath($filePath);
            }
            OssTool::publicUpload('', $ossKey, $filePath, $options);
            return $ossKey;
        } catch (\Exception $e) {
            Log::info(
                $e->getFile() . ' ' .
                $e->getLine() . ' ' .
                $e->getMessage()
            );
            return '';
        }
    }

    /**
     * 生成通用的ossKey
     *
     * @param string $filePath
     * @param string $fileTypeName
     *
     * @return string
     */
    public static function generateGenericOssKeyByFilePath($filePath, $fileTypeName = '')
    {
        if (!file_exists($filePath)) return '';
        $ext = self::getFileExt($filePath);
        if (empty($ext)) return '';
        $year_str = date('Y');
        $month_str = date('m');
        $date_str = date('d');
        $uuid = date('YmdHis') . substr(implode(null, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
        $fileName = $uuid . '.' . $ext;
        $oss_key = $year_str . '/' . $month_str . '/' . $date_str . '/' . $fileName;
        if ($fileTypeName) {
            $oss_key = $fileTypeName . '/' . $oss_key;
        }
        return $oss_key;
    }

    /**
     * 获取文件后缀
     *
     * @param $filePath
     *
     * @return mixed|string
     */
    public static function getFileExt($filePath)
    {
        if ($filePath) {
            return pathinfo($filePath, PATHINFO_EXTENSION);
        }
        return '';
    }

    /***
     * 生成随机数
     *
     * @param $length
     *
     * @return string
     */
    public static function randomCode($length)
    {
        $key = "";
        $pattern = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        for ($i = 0; $i < $length; $i++) {
            $key .= $pattern{mt_rand(0, 9)}; //生成php随机数
        }
        return $key;
    }

    /***
     * 新建目录
     *
     * @param $path
     */
    public static function mkFolder($path)
    {
        if (!is_readable($path)) {
            is_file($path) or mkdir($path, 0766);
        }
    }

    /***
     * 保存图片路径
     *
     * @param string $img_dir_absolute_path
     *
     * @return string
     */
    public static function getFileSaveRelativeDir($img_dir_absolute_path = 'uploads')
    {
        self::mkFolder(public_path($img_dir_absolute_path));
        $dir_absolute_path = $img_dir_absolute_path . DIRECTORY_SEPARATOR . date('Y') . DIRECTORY_SEPARATOR;
        self::mkFolder(public_path($dir_absolute_path));
        $dir_absolute_path .= date('m');
        self::mkFolder(public_path($dir_absolute_path));
        return $dir_absolute_path;
    }

    /***
     *  静态资源外部访问链接处理，如果是链接头带有http，就判定为完整链接，否则认定为oss存储对象
     *
     * @param $object_url
     *
     * @return string
     */
    public static function getPublicObjectURL($object_url)
    {
        if (empty($object_url)) {
            return '';
        }
        $object_url_substr = substr($object_url, 0, 4);
        if ($object_url_substr !== 'http') {
            $object_url = OSSTool::getPublicObjectURL('', $object_url);
        }
        return $object_url;
    }


    /**
     * 导出excel
     *
     * @param array $cellData = [['学号', '姓名'],['10001', '李四']]
     * @param string $format
     *
     * @return string
     */
    public static function exportExcel(array $cellData, $format = 'xls')
    {
        $store_folder = self::getExcelRelativeDir('uploads');
        $file_name = date('YmdHis') . rand(1000, 9999);

        Excel::create($file_name, function ($excel) use ($cellData) {
            $excel->sheet('export', function ($sheet) use ($cellData) {
                $sheet->rows($cellData); // 追加多行
            });
        })->store($format, public_path($store_folder));

        return asset($store_folder . '/' . $file_name . '.' . $format);
    }

    /**
     * 导入excel
     *
     * @param  $file 上传的文件
     *
     * @return 数据数组
     */
    public static function importExcel($file, $isDelete = false)
    {
        $tmp_path = $file->path();
        $store_folder = self::getExcelRelativeDir('uploads');
        $file_name = date('YmdHis') . rand(1000, 9999);
        $file_path = $store_folder . '/' . $file_name . '.xls';
        move_uploaded_file($tmp_path, $file_path);

        $data = Excel::load($file_path)->getSheet(0)->toArray();
        if ($isDelete) {
            @unlink($file_path);
        }
        return $data;
    }

    /**
     * 创建导入/导出excel目录
     *
     * @param  String $type 'import'/'export'
     * @param  string $dir_absolute_path
     *
     * @return string
     */
    public static function getExcelRelativeDir($type, $dir_absolute_path = 'uploads')
    {
        self::mkFolder(public_path($dir_absolute_path));
        $dir_absolute_path = $dir_absolute_path . DIRECTORY_SEPARATOR . date('Y') . DIRECTORY_SEPARATOR;
        self::mkFolder(public_path($dir_absolute_path));
        $dir_absolute_path .= date('m') . DIRECTORY_SEPARATOR;
        self::mkFolder(public_path($dir_absolute_path));
        $dir_absolute_path .= $type;
        self::mkFolder(public_path($dir_absolute_path));
        return $dir_absolute_path;
    }

    /***
     * 发起网络请求
     *
     * @param array $data
     *
     * @return mixed|\Psr\Http\Message\StreamInterface
     */
    public static function sendRequest(array $data)
    {
        try {
            $url = $data['url'];
            $client = new Client();
            $params = $data['params']  ?? [];
            $method = $data['request_method'] ?? 'POST';
            $timeout = $data['timeout'] ?? 10;
            $options = [
                'form_params' => $params,
                'timeout'     => $timeout
            ];
            if (isset($data['headers'])) {
                $options['headers'] = $data['headers'];
            }
            $response = $client->request($method, $url, $options);
            $result = $response->getBody();
            return json_decode($result, true);
        } catch (ClientException $e) {
            return [
                'code'    => -1,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * Validator 验证
     *
     * @param Request $request
     * @param array $validatorRules
     *
     * @return mixed
     */
    public static function store(Request $request, array $validatorRules)
    {
        return Validator::make($request->all(), $validatorRules);
    }

    /**
     * 获取客户端IP
     * @return string
     */
    public static function getRealIpAddr()
    {
        $ip = '';
        if (isset($_SERVER['HTTP_CLIENT_IP']) &&
            !empty($_SERVER['HTTP_CLIENT_IP'])
        ) {
            //check ip from share internet
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])
            && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])
        ) {
            //to check ip is pass from proxy
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else {
            $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
        }
        return $ip;
    }

    /**
     * 获取UUId
     * @return mixed
     */
    public static function getOrderUuid()
    {
        $uuid = (string)Str::orderedUuid();
        return str_replace('-', '', $uuid);
    }


}